﻿using Dyao.Repository.Abstractions;
using Dyao.Book.Application.Abstractions;
using Dyao.Book.Contract;
using Dyao.Book.Core;
using Dyao.Book.Entity;
using Foundation.Core;
using Foundation.Uow;

namespace Dyao.Book.Application
{
    public class TaskCenterRuleApplication : BaseApplication, ITaskCenterRuleApplication
    {
        private readonly ITaskCenterRuleRepository _taskCenterRuleRepository;

        public TaskCenterRuleApplication(ITaskCenterRuleRepository taskCenterRuleRepository)
        {
            this._taskCenterRuleRepository = taskCenterRuleRepository;
        }

        /// <summary>
        /// 获取任务中心规则列表
        /// </summary>
        /// <param name="idList">idList</param>
        /// <param name="cancellationToken">cancellationToken</param>
        /// <returns></returns>
        public async Task<List<TaskCenterRuleDto>> GetTaskCenterRuleModelListAsync(List<int> idList, CancellationToken cancellationToken = default)
        {
            if (idList == null) return null;
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var taskCenterRuleList = await _taskCenterRuleRepository.GetTaskCenterRuleListAsync(idList, cancellationToken);
                return taskCenterRuleList;
            }
        }

        /// <summary>
        /// 获取所有规则
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<TaskCenterRuleDto>> GetListAsync(CancellationToken cancellationToken = default)
        {
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var entities = await _taskCenterRuleRepository.GetListAsync(cancellationToken);

                var list = ObjectMapper.Map<List<TaskCenterRuleEntity>, List<TaskCenterRuleDto>>(entities);

                return list;
            }
        }

        /// <summary>
        /// 获取规则执行器的配置信息
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<TaskCenterRuleExecutorSettingInfoDto>> GetAllRuleExecutorSettingInfoListAsync(CancellationToken cancellationToken = default)
        {
            var rules = TaskCenterRuleManager.GetTaskCenterRules();
            var jsonConvertor = GetService<IJsonSerializer>();
            var list = new List<TaskCenterRuleExecutorSettingInfoDto>();

            foreach (var item in rules.Values)
            {
                string jsonFomat = null;

                if (item.IsNeedLoadSettings
                    && item.SettingType != null
                    && !item.SettingType.IsValueType
                    && !item.SettingType.IsPrimitive
                    && !item.SettingType.IsEnum
                    && item.SettingType != typeof(decimal))
                {
                    var obj = Activator.CreateInstance(item.SettingType);
                    jsonFomat = jsonConvertor.Serialize(obj, indented: true);
                }

                list.Add(new TaskCenterRuleExecutorSettingInfoDto
                {
                    RuleKey = item.RuleKey,
                    DisplayName = item.Name,
                    HasSettings = item.HasSettings,
                    IsNeedLoadSettings = item.IsNeedLoadSettings,
                    SettingJsonFormat = jsonFomat
                });
            }

            return await Task.FromResult(list);
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task AddAsync(TaskCenterRuleAddOrEditDto model, CancellationToken cancellationToken = default)
        {
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var rule = TaskCenterRuleManager.GetRuleExcutorTypeByKey(model.RuleKey);

                if (rule == null)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditExecutorNotFound, $"规则[{model.RuleKey}]不存在");
                }

                if (rule.IsNeedLoadSettings && model.RuleSettings.IsNullOrWhiteSpace())
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditRuleSettingIsEmpty, "规则配置不能为空");
                }

                //无需配置的规则执行器的记录只能存在一个
                if (!rule.IsNeedLoadSettings)
                {
                    var hasRule = await _taskCenterRuleRepository.IsExistAsync(r => r.RuleKey == model.RuleKey, cancellationToken);

                    if (hasRule)
                    {
                        throw new BusinessException(DataExceptionCode.TaskCenterRuleEditNoSettingRuleExists, $"规则[{model.RuleKey}]：属于无配置规则，已存在相同的规则。");
                    }
                }

                var entity = ObjectMapper.Map<TaskCenterRuleAddOrEditDto, TaskCenterRuleEntity>(model);
                entity.ID = 0;

                await _taskCenterRuleRepository.InsertAsync(entity, false, cancellationToken);

                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="model"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task EditAsync(TaskCenterRuleAddOrEditDto model, CancellationToken cancellationToken = default)
        {
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var rule = TaskCenterRuleManager.GetRuleExcutorTypeByKey(model.RuleKey);

                if (rule == null)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditExecutorNotFound, $"规则[{model.RuleKey}]不存在");
                }

                if (rule.IsNeedLoadSettings && model.RuleSettings.IsNullOrWhiteSpace())
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditRuleSettingIsEmpty, "规则配置不能为空");
                }

                var entity = await _taskCenterRuleRepository.FindAsync(model.Id, cancellationToken);
                if (entity == null)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditIdNotFound, "规则不存在");
                }

                if (entity.RuleKey != model.RuleKey)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleEditKeyNotEquals, "规则Key不允许更改");
                }

                ObjectMapper.Map(model, entity);

                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task DeleteAsync(int id, CancellationToken cancellationToken = default)
        {
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var entity = await _taskCenterRuleRepository.FindAsync(id, cancellationToken);
                if (entity == null)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleDelIdNotFound, "记录不存在");
                }

                var idStr = $",{id},";
                var isExists = await GetService<ITaskCenterSettingsRepository>().IsExistAsync(s => s.RuleIds.Contains(idStr), cancellationToken);

                if (isExists)
                {
                    throw new BusinessException(DataExceptionCode.TaskCenterRuleDelHasUse, "该规则正在使用中！");
                }

                await _taskCenterRuleRepository.DeleteAsync(entity, false, cancellationToken);

                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }
    }
}
